#include "tal_log.h"
#include "tal_memory.h"
#include "tal_system.h"
#include "tal_sw_timer.h"
#include "tal_attribute_rw.h"
#include "app_handle.h"
#include "app_cluster_private_tuya.h"


#define PRINTF_BUFF_SIZE    512
STATIC char printbuff[PRINTF_BUFF_SIZE] = {0};
VOID raw_data_debug_printf(CHAR_T *prefix, UCHAR_T *data, UINT_T len)
{
    memset(printbuff, 0, PRINTF_BUFF_SIZE);

    if (len > ((PRINTF_BUFF_SIZE - 1) / 2))
    {
        len = (PRINTF_BUFF_SIZE - 1) / 2;
    }
    
    for (UINT_T i = 0; i < len; i++)
    {
        UCHAR_T b = (data[i] >> 4) & 0xF;
        printbuff[i*2+0] = (char)((b < 10) ? ('0' + b) : ('A' + (b - 10)));
        b = data[i] & 0xF;
        printbuff[i*2+1] = (char)((b < 10) ? ('0' + b) : ('A' + (b - 10)));
        if (i == (PRINTF_BUFF_SIZE / 2 - 1))
        {
            printbuff[PRINTF_BUFF_SIZE - 1] = 0;
            break;
        }
    }
    TAL_PR_DEBUG("%s len=%d,data=%s", prefix, len, printbuff);
}

/**
* @brief this function will handle uart received frame data  
* @param[in] {dpid}   dp id
* @param[in] {value}  dp data 
* @param[in] {length} lenght of dp data 
* @return  handle result 
*/
OPERATE_RET __app_private_tuya_dpid_handle(UINT8_T dpid,const UINT8_T *value, UINT8_T length)
{
    /* only list of function, mcu need realize these fuction*/
    return OPRT_OK;
}

/**
 * @note app private_tuya command handler
 * @param [in]{UCHAR_T} onoff
 * @param [in]{ZIGBEE_CMD_T} single or group transmit cmd
 * @return: none
 */
STATIC VOID_T __app_private_tuya_cmd_set_value_handler(ZIGBEE_CMD_T cmd_type, UINT8_T *data, UINT8_T len)
{
    TAL_SEND_QOS_E QOS = QOS_1;
    ULONG_T delay_ms = 0;
    if (cmd_type == ZIGBEE_CMD_GROUP)
    {
        delay_ms = 10000 + tal_system_get_random(1000);
        QOS = QOS_0;
    }
    app_private_tuya_report_value(CMD_WRITE_ATTRIBUTES_NO_RESPONSE_COMMAND_ID, QOS, delay_ms, data, len);

    UINT8_T dp_id = data[2];
    UINT16_T dp_len = data[4] * 0x100;
    dp_len += data[5];
    OPERATE_RET ret = __app_private_tuya_dpid_handle(dp_id, (const UINT8_T *)(data + 6), dp_len);
    if (ret == OPRT_OK)
    {
        app_handle_start(TRUE);
    }
}

/**
 * @brief 
 * 
 * @param Qos 
 * @param delay_ms 
 * @param onoff 
 * @return VOID_T 
 */
VOID_T app_private_tuya_report_value(UINT8_T command_id, TAL_SEND_QOS_E qos, USHORT_T delay_ms, UINT8_T *data, UINT8_T len)
{
    TAL_ZG_SEND_DATA_T send_data;

    tal_system_memset(&send_data, 0, sizeof(TAL_ZG_SEND_DATA_T));

    send_data.delay_time = delay_ms;
    send_data.random_time = 0;
    send_data.zcl_id = ZCL_ID_PRIVATE_TUYA;
    send_data.qos = qos;
    send_data.direction = ZG_ZCL_DATA_SERVER_TO_CLIENT;
    send_data.frame_type = ZG_ZCL_FRAME_TYPE_SPEC_TO_CLUSTER;
    send_data.command_id = command_id;

    // unicast to gateway
    send_data.addr.mode = SEND_MODE_DEV;
    send_data.addr.type.dev.dst_addr = TUYA_GATEWAY_ADDRESS;
    send_data.addr.type.dev.dst_ep = 0x01;
    send_data.addr.type.dev.src_ep = TUYA_PRIMARY_ENDPOINT;
    send_data.addr.type.dev.cluster_id = CLUSTER_PRIVATE_TUYA_CLUSTER_ID;

    send_data.data.private.len = len;
    tal_system_memcpy((send_data.data.private.data), data, len);
    raw_data_debug_printf("report", data, len);
    tal_zg_clear_send_data(ZG_CLEAR_ALL_ZCL_ID, &send_data.zcl_id);
    tal_zg_send_data(&send_data, NULL, 2000);
}

/**
 * @brief handle zcl on/off cluster command
 * 
 * @param cmd 
 * @param payload 
 * @param payload_len 
 * @param cmd_type 
 * @return OPERATE_RET 
 */
OPERATE_RET app_private_tuya_cluster_handler(UCHAR_T cmd, UINT8_T *payload, UINT8_T payload_len, ZIGBEE_CMD_T cmd_type)
{
    raw_data_debug_printf("hanler", payload, payload_len);
    switch (cmd)
    {
    case TY_CMD_SET_PRIVATE_TUYA_CMD_ID:
    {
        __app_private_tuya_cmd_set_value_handler(cmd_type, payload, payload_len);
        break;
    }
    default:
        break;
    }
    return OPRT_OK;
}

